﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace System.Web.Mvc
{
    public static class PagerExtend
    {
        public static MvcHtmlString SPager<T>(this HtmlHelper htmlHelper, SPagedList<T> model, string pnoname, string cssClass, string updateTargetId, string DataFormId)
        {
            if (model.TotalItemCount <= 0)
                return new MvcHtmlString("");
            string tid = "spage_" + DateTime.Now.Millisecond;
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<div class=\"spager {0}\" id=\"{1}\" updateTargetId=\"{2}\" DataFormId=\"{3}\" pnoName=\"{4}\">\r\n", cssClass ?? "", tid, updateTargetId, DataFormId, pnoname);
            //首
            Appenda(sb, 1, "首页");
            //上一页
            if (model.CurrentPageIndex != 1)
            {
                Appenda(sb, model.CurrentPageIndex - 1, "上一页");
            }
            else
            {
                Appenda(sb, -1, "上一页");
            }

            //页
            if (model.TotalPageCount <= 10)
            {
                for (int i = 1; i <= model.TotalPageCount; i++)
                {
                    Appenda(sb, i, i.ToString(), model.CurrentPageIndex == i);
                }
            }
            else
            {
                int si = 1;
                int ei = 10;
                if (model.CurrentPageIndex <= 5) { }
                else if (model.CurrentPageIndex > model.TotalPageCount - 5)
                {
                    si = model.TotalPageCount - 9;
                    ei = model.TotalPageCount;
                }
                else
                {
                    si = model.CurrentPageIndex - 4;
                    ei = model.CurrentPageIndex + 5;
                }
                if (si != 1)
                {
                    Appenda(sb, si / 2, "...");
                }
                for (int k = si; k <= ei; k++)
                {
                    Appenda(sb, k, k.ToString(), model.CurrentPageIndex == k);
                }
                if (ei != model.TotalPageCount)
                {
                    Appenda(sb, model.TotalPageCount - (model.TotalPageCount - ei) / 2, "...");
                }
            }
            //下一页 
            if (model.CurrentPageIndex == model.TotalPageCount)
            {
                Appenda(sb, -1, "下一页");
            }
            else
            {
                Appenda(sb, model.CurrentPageIndex + 1, "下一页");
            }
            //尾页
            Appenda(sb, model.TotalPageCount, "尾页");
            sb.AppendFormat("\r\n</div>");

            return new MvcHtmlString(sb.ToString());

        }
        private static void Appenda(StringBuilder sb, int pno, string txt, bool iscurrent = false)
        {
            if (iscurrent || pno <= 0)
            {
                sb.AppendFormat("\r\n<a href=\"javascript:void(0);\" disabled=\"disabled\" >{0}</a>\r\n", txt);

            }
            else
            {
                sb.AppendFormat("\t<a href=\"javascript:void(0);\" class=\"{1}\" onclick=\"_spgo(this,{0})\">{2}</a>\r\n", pno, iscurrent ? "curr" : "", txt);
            }
        }

        public static MvcHtmlString SPagerScript(this HtmlHelper htmlHelper)
        {
            string s = @"
            var _spformdata = undefined;
            function _spgo(sender, pno) {
                var pager = $(sender).parent('.spager').first();
                var updateTargetId = pager.attr('updateTargetId');
                var pnoName = pager.attr('pnoName');
                var DataFormId = pager.attr('DataFormId');
                var action = $(DataFormId).attr('action');
            
                var narr = $(DataFormId).serializeArray();
                narr.push({ name: pnoName, value: pno });
            
                $.ajax({
                    url: action,
                    data: _toformdata(narr),
                    type: 'post',
                    success: function (data) {
                        $(updateTargetId).html(data);
                    }
                });
            }
            
            function _copyarr(arr) {
                var narr = new Array();
                for (var i in arr) {
                    narr.push({ name: arr[i]['name'], value: arr[i]['value'] });
                }
                return narr;
            }
            
            function _toformdata(arr) {
                var data = {};
                for (var i in arr) {
                    data[arr[i]['name']] = arr[i]['value'];
                }
                return data;
            }
            
            function _spsearch(sender) {
                var pform = $(sender).parents('form').first();
                var updateTargetId = pform.attr('updateTargetId');
                var action = pform.attr('action');
                //var tt = pform.serialize();
                $.ajax({
                    url: action,
                    data: pform.serialize(),
                    type: 'post',
                    success: function (data) {
                        _spformdata = undefined;
                        $(updateTargetId).html(data);
                    }
                });
            }";
            s = "<script>\r\n" + s + "\r\n</script>";
            return new MvcHtmlString(s);
        }

        /// <summary>
        /// 显示DisplayNameFor
        /// </summary>
        /// <returns></returns>
        public static IHtmlString DisplayNameFor<TModel, TValue>(this HtmlHelper<SPagedList<TModel>> html, Expression<Func<TModel, TValue>> expression)
        {
            return GetDisplayName(expression);
        }

        /// <summary>
        /// 显示DisplayNameFor
        /// </summary>
        /// <returns></returns>
        private static IHtmlString GetDisplayName<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, new ViewDataDictionary<TModel>());
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
            return new MvcHtmlString(HttpUtility.HtmlEncode(resolvedDisplayName));
        }
    }

    public class SPagedList<T> : IEnumerable<T>
    {
        private int currentpageindex;
        private int pagesize;
        private int totalitemcount;
        private int totalpagecount;

        private IEnumerable<T> plist;

        public SPagedList(IEnumerable<T> currentPageItems, int pageIndex, int pageSize, int totalItemCount)
        {
            plist = currentPageItems;
            this.currentpageindex = pageIndex;
            this.pagesize = pageSize;
            this.totalitemcount = totalItemCount;
            calcpagecount();
        }

        //计算页数
        private void calcpagecount()
        {
            if (this.totalitemcount <= 0)
                this.totalpagecount = 0;
            else if (this.pagesize <= 0)
            {
                this.totalpagecount = 1;
            }
            else if (this.pagesize >= this.totalitemcount)
            {
                this.totalpagecount = 1;
            }
            else
            {
                this.totalpagecount = this.totalitemcount / this.pagesize;
                if (this.totalpagecount != this.totalitemcount / ((double)this.pagesize))
                {
                    this.totalpagecount += 1;
                }
            }
        }

        public int CurrentPageIndex
        {
            get
            {
                return this.currentpageindex;
            }
        }

        public int PageSize
        {
            get { return this.pagesize; }
        }

        public int TotalItemCount
        {
            get { return this.totalitemcount; }
        }
        public int TotalPageCount
        {
            get { return this.totalpagecount; }
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return plist.GetEnumerator();
        }


        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}